﻿using DM_Sqlite.MappingClass;
using DM_TOOLS.Tools;
using DM_TOOLS.Tools.SMTP;
using DMSystem_Sqlite_WebAPI.Utility;
using DMSystem_Sqlite_WebAPI.Utility.Feishu;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DMSystem_Sqlite_WebAPI.Utility.Quartz
{
    public class MyJobforLog : IJob
    {
        private readonly ILogger<MyJobforLog> _logger;
        private readonly IMemoryCache _memoryCache;//内存缓存
        private readonly IHubContext<SiginalrHub> _hubContext;//signalr
        public MyJobforLog(ILogger<MyJobforLog> logger, IMemoryCache memoryCache, IHubContext<SiginalrHub> hubContext)
        {
            _logger = logger;
            _memoryCache = memoryCache;
            _hubContext = hubContext;
        }
        public async Task Execute(IJobExecutionContext context)
        {
            var map = context.JobDetail.JobDataMap;
            string? logpath = map.GetString("logpath");
            try
            {
                if (logpath != null)
                {
                    Console.WriteLine($"{logpath} in {Thread.CurrentThread.ManagedThreadId} run at {DateTime.Now}");
                    var userprop = _memoryCache.Get<dm_props_user>(logpath);
                    var adminprop = _memoryCache.Get<dm_props_admin>("datamonitoradminpara");
                    //获得最新的log文件
                    var file = FileOperator.GetLatestextFiles(logpath, "*.log").LastOrDefault();
                    //获得缓存里的文件名
                    var lastfilename = _memoryCache.Get<string>(logpath + "logname");
                    //比较最新产生的文件名是否跟缓存里的一样，一样说明没有新文件产生
                    if (file != null)
                    {
                        if (file.Name != lastfilename)
                        {
                            if (userprop != null && adminprop != null)
                            {
                                //最新文件名存入缓存中
                                //await Console.Out.WriteLineAsync($"监控到新文件{file.Name}");
                                _memoryCache.Set<string>(logpath + "logname", file.Name);
                                string[] contents = await File.ReadAllLinesAsync(file.FullName);
                                var keywords = adminprop.logkeywords.Split(";");
                                //识别日志里的错误
                                var res = SMTPWarnContent.CreateWarnContentforLog(contents, keywords, userprop.can0, userprop.idcount, file.Name);
                                #region 开始发送数据
                                if (res != "")
                                {
                                    _logger.LogError(res);
                                    foreach (var i in SiginalrHub.user)
                                    {
                                        await _hubContext.Clients.Group(i).SendAsync("loginfo", userprop.logpath, res);
                                    }
                                    //先获得mailconfig配置缓存
                                    var mailconfig = _memoryCache.Get<SMTPConfig>(userprop.vehicle + "mailconfig");
                                    if (mailconfig != null)
                                    {
                                        //再从缓存里看有没有mailerror，如果没有说明第一次碰到error
                                        var firstmailerror = _memoryCache.Get<string>(userprop.vehicle + "logerror");
                                        if (firstmailerror == null)
                                        {
                                            //第一次碰到错误发送邮件
                                            //await SMTPMail.SendEmailAsync(mailconfig, res);
                                            await FeishuRobot.SendFeishuMessage("车号：" + userprop.vehicle + "-" + userprop.ip + "(" + userprop.remarks + ")" + "日志：" + res);
                                            //如果第一次碰到，则创建缓存并设置为第一次的错误信息
                                            var mailerror = _memoryCache.GetOrCreate<string>(userprop.vehicle + "logerror", value =>
                                            {
                                                return res;
                                            });
                                            //再创建缓存记录第一次发送的时间
                                            var starttime = _memoryCache.GetOrCreate<DateTime>(userprop.vehicle + "logsendtime", value =>
                                            {
                                                return DateTime.Now;
                                            });
                                        }
                                        //说明缓存里已经有mailerror了，不是第一次出现问题了
                                        else
                                        {
                                            //判断当前的与上一次的是否问题一致，不一致再发邮件，再覆盖记录发送时间
                                            if (res != firstmailerror)
                                            {
                                                _memoryCache.Set<string>(userprop.vehicle + "logerror", res);
                                                //await SMTPMail.SendEmailAsync(mailconfig, res);
                                                await FeishuRobot.SendFeishuMessage("车号：" + userprop.vehicle + "-" + userprop.ip + "(" + userprop.remarks + ")" + "日志：" + res);
                                                _memoryCache.Set<DateTime>(userprop.vehicle + "logsendtime", DateTime.Now);
                                            }
                                            //如果一致，则判断是否经过了1小时，然后再发送邮件提醒
                                            else
                                            {
                                                //先获取上一次缓存里的发送时间
                                                var lastsendtime = _memoryCache.Get<DateTime>(userprop.vehicle + "logsendtime");
                                                if (SMTPWarnContent.IsPastOneHour(lastsendtime, mailconfig.emailtimespan))
                                                {
                                                    //await SMTPMail.SendEmailAsync(mailconfig, res);
                                                    await FeishuRobot.SendFeishuMessage("车号：" + userprop.vehicle + "-" + userprop.ip + "(" + userprop.remarks + ")" + "日志：" + res);
                                                    _memoryCache.Set<DateTime>(userprop.vehicle + "logsendtime", DateTime.Now);
                                                }
                                            }
                                        }
                                    }

                                }

                                #endregion
                            }

                        }
                    }
                }

            }
            catch (Exception ex)
            {
                _logger.LogError(ex.Message);
                foreach (var i in SiginalrHub.user)
                {
                    await _hubContext.Clients.Group(i).SendAsync("logexception", logpath, ex.Message);
                }

            }
        }
    }
}
